82장. Secrets Manager와 Parameter Store
이 장에서 말하고자 하는 것
애플리케이션은 다음 같은 비밀을 다룬다.
- DB 비밀번호
- API 키
- OAuth 클라이언트 시크릿
- 인증서 / 키 파일
이걸 어디에 두고, 어떻게 가져올까?
AWS의 두 가지 옵션:
- AWS Secrets Manager
- AWS Systems Manager Parameter Store
이름이 비슷한데 자리가 다르다.
1. 둘의 차이
| 항목 | Secrets Manager | Parameter Store |
|---|---|---|
| 본질 | 비밀 전용 | 설정/비밀 둘 다 |
| 자동 회전 | ✅ (Lambda로 구현) | ❌ |
| 가격 | 비밀당 월 비용 + 호출당 | 표준 무료 + 호출 |
| 크기 | 64KB | 표준 4KB / 고급 8KB |
| 버전 관리 | 자동 | 자동 |
| RDS 통합 | ✅ (자동 회전 내장) | 부분 |
비밀은 Secrets Manager, 단순 설정은 Parameter Store
가벼운 운영에서는 Parameter Store SecureString 으로도 충분
2. Secrets Manager — 비밀 전용
secret "orders/db-password"
├─ 현재 버전: AWSCURRENT
├─ 옛 버전: AWSPREVIOUS
└─ Rotation Lambda: 30일마다 DB 비밀번호 갱신
- RDS · Aurora 비밀번호를 자동 회전
- KMS로 자동 암호화
- JSON 객체 통째로 저장 가능 (
{ "username":"...", "password":"..." })
3. Parameter Store — 설정 + 가벼운 비밀
/orders/prod/api-url → "https://internal/orders"
/orders/prod/db-password → SecureString (KMS 암호화)
/orders/prod/feature-x → "enabled"
- 계층적 이름 (
/...) - 일반 String · 안전한 SecureString · StringList
- 무료 (표준 등급)
비밀은 SecureString을 쓰고 KMS 키를 지정한다.
4. ECS Task와의 통합
가장 흔한 사용법.
Task Definition의 container.secrets:
- DB_PASSWORD → arn:aws:secretsmanager:...:secret:orders/db-password
- API_KEY → arn:aws:ssm:...:parameter/orders/prod/api-key
ECS가 Task 시작 시점에 가져와 환경 변수로 주입 한다.
컨테이너 안에서:
process.env.DB_PASSWORD ← 그냥 평범한 환경 변수처럼 쓰면 됨
애플리케이션 코드는 비밀 가져오는 로직을 가지지 않아도 된다
Execution Role에 GetSecretValue 권한만 있으면 끝
5. 비밀이 코드/저장소에 남지 않게 하기
1. Git에 비밀 커밋 금지
.env 같은 파일에 박지 않는다. git-secrets 같은 도구로 자동 검사.
2. Terraform state에도 평문 비밀 X
manage_master_user_password = true 같은 옵션을 써서 Secrets Manager가 알아서 만들도록.
3. 로그에 비밀이 출력되지 않게
실수로 console.log(config) 했을 때 비밀이 CloudWatch에 들어가지 않도록.
6. 자동 회전 — Secrets Manager의 진가
30일마다 자동으로 새 비밀번호 생성
↓
1. Secrets Manager가 새 비밀번호 발급
2. DB에 새 비밀번호 설정
3. Secrets Manager의 AWSCURRENT 업데이트
4. 애플리케이션은 다음 GetSecretValue 호출에서 새 비밀번호를 받음
- RDS · Aurora는 내장 회전 기능 제공
- DocumentDB · Redshift도 일부 지원
- 일반 비밀은 직접 Lambda 작성
사람이 비밀번호를 손으로 바꾸는 일이 사라진다
7. 우리 서비스에서
Secrets Manager:
orders/db-password ← Multi-AZ RDS, 자동 회전 30일
users/db-password ← 같음
payments/db-password ← 같음
third-party/stripe-key
third-party/twilio-token
Parameter Store:
/orders/prod/api-url
/orders/prod/feature-flags
/orders/prod/log-level
비밀은 Secrets Manager, 단순 설정은 Parameter Store.
8. 직접 확인해보기 — CLI
Secrets Manager
aws secretsmanager create-secret \
--name orders/db-password \
--secret-string '{"username":"app","password":"<auto>"}'
aws secretsmanager get-secret-value --secret-id orders/db-password
# 회전 설정
aws secretsmanager rotate-secret \
--secret-id orders/db-password \
--rotation-lambda-arn <lambda-arn> \
--rotation-rules AutomaticallyAfterDays=30
Parameter Store
aws ssm put-parameter \
--name /orders/prod/api-url \
--value "https://internal/orders" \
--type String
aws ssm put-parameter \
--name /orders/prod/api-key \
--value "secret123" \
--type SecureString \
--key-id alias/prod-secrets
aws ssm get-parameter \
--name /orders/prod/api-key \
--with-decryption
9. 코드로는 이렇게 생겼다 — Terraform
# Secrets Manager
resource "aws_secretsmanager_secret" "orders_db" {
name = "orders/db-password"
description = "orders RDS master password"
kms_key_id = aws_kms_key.secrets.arn
}
# RDS가 자동으로 비밀번호를 만들고 회전하도록 두는 게 더 깔끔
resource "aws_db_instance" "orders" {
...
manage_master_user_password = true
master_user_secret_kms_key_id = aws_kms_key.secrets.id
}
# Parameter Store
resource "aws_ssm_parameter" "api_url" {
name = "/orders/prod/api-url"
type = "String"
value = "https://internal/orders"
}
resource "aws_ssm_parameter" "feature_flag" {
name = "/orders/prod/feature-x"
type = "String"
value = "enabled"
}
ECS Task Definition의 secrets:
secrets = [
{
name = "DB_PASSWORD"
valueFrom = aws_secretsmanager_secret.orders_db.arn
},
{
name = "API_URL"
valueFrom = aws_ssm_parameter.api_url.arn
}
]
이렇게 두면 컨테이너 안에서는 그냥 환경 변수.
10. 이렇게 쓰면 망한다 — 안티패턴
안티패턴 1. 비밀을 평문 환경 변수로 박는다
Task Definition · 배포 로그 · CloudFormation에 평문이 남는다.
항상
secrets로 가져온다
안티패턴 2. .env 파일을 Git에 커밋
가장 흔한 사고. 회수도 어렵다.
안티패턴 3. 비밀 회전을 한 번도 안 한다
유출된 비밀이 영원히 살아 있다.
안티패턴 4. 모든 비밀을 한 시크릿에 합친다
한 비밀의 회수 / 회전이 다른 비밀에 영향을 준다.
비밀 단위는 좁게 — 서비스 · 용도 별로
11. 한 줄로 정리
비밀은 Secrets Manager로 자동 회전 · 자동 주입,
단순 설정은 Parameter Store — 코드/저장소에 평문 비밀을 남기지 않는다
12. 이 장의 핵심 정리
- 비밀 전용은 Secrets Manager, 일반 설정은 Parameter Store.
- RDS는 manage_master_user_password 로 Secrets Manager 자동 관리가 가능하다.
- ECS의
secrets필드로 컨테이너에 자동 주입 — 코드는 평범한 환경 변수처럼 쓴다. - 자동 회전 (Secrets Manager) 으로 비밀의 수명을 통제한다.
- 비밀은 좁게 — 서비스 · 용도 단위 분리.
- Git · 로그 · Terraform state에 평문 비밀이 남지 않게 한다.